home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / grapdrvs / hpsbutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-09  |  32.2 KB  |  991 lines

  1. /******************************************************************************
  2. * This horrible piece of code is an extract from SBUTILS demo of starbase.    *
  3. *   I do not want to nor have any interest into understanding this horror     *
  4. * story. All I want is a starbase window under X11 using HPUX.                *
  5. *   This is an extremely displeasing situation that must be improved by HP.   *
  6. *                                       Gershon Elber,      February 1995.  *
  7. ******************************************************************************/
  8.  
  9.  
  10. /******************************************************************************
  11.  *
  12.  * This file contains a set of example utility procedures; procedures that can
  13.  * help a "window-smart" Starbase or PHIGS program determine information about
  14.  * a device, and create image and overlay plane windows.  To use these
  15.  * utilities, #include "wsutils.h" and compile this file and link the results
  16.  * with your program.
  17.  *
  18.  ******************************************************************************/
  19.  
  20. #include <X11/X.h>
  21. #include <X11/Xlib.h>
  22. #include <X11/Xutil.h>
  23. #include <X11/XHPlib.h>
  24. #include <stdio.h>
  25. #include "xsbdrvs.h"
  26.  
  27.  
  28. #define STATIC_GRAY    0x01
  29. #define GRAY_SCALE    0x02
  30. #define PSEUDO_COLOR    0x04
  31. #define TRUE_COLOR    0x10
  32. #define DIRECT_COLOR    0x11
  33.  
  34.  
  35. static void    SetServerOverlayVisualsProperty();
  36. static int    weCreateServerOverlayVisualsProperty = False;
  37.  
  38.  
  39. /******************************************************************************
  40.  *
  41.  * GetXVisualInfo()
  42.  *
  43.  * This routine takes an X11 Display, screen number, and returns whether the
  44.  * screen supports transparent overlays and three arrays:
  45.  *
  46.  *    1) All of the XVisualInfo struct's for the screen.
  47.  *    2) All of the OverlayInfo struct's for the screen.
  48.  *    3) An array of pointers to the screen's image plane XVisualInfo
  49.  *       structs.
  50.  *
  51.  * The code below obtains the array of all the screen's visuals, and obtains
  52.  * the array of all the screen's overlay visual information.  It then processes
  53.  * the array of the screen's visuals, determining whether the visual is an
  54.  * overlay or image visual.
  55.  *
  56.  * If the routine sucessfully obtained the visual information, it returns zero.
  57.  * If the routine didn't obtain the visual information, it returns non-zero.
  58.  *
  59.  ******************************************************************************/
  60.  
  61. int GetXVisualInfo(display, screen, transparentOverlays,
  62.            numVisuals, pVisuals,
  63.            numOverlayVisuals, pOverlayVisuals,
  64.            numImageVisuals, pImageVisuals)
  65.  
  66.     Display    *display;        /* Which X server (aka "display"). */
  67.     int        screen;            /* Which screen of the "display". */
  68.     int        *transparentOverlays;    /* Non-zero if there's at least one
  69.                      * overlay visual and if at least one
  70.                      * of those supports a transparent
  71.                      * pixel. */
  72.     int        *numVisuals;        /* Number of XVisualInfo struct's
  73.                      * pointed to to by pVisuals. */
  74.     XVisualInfo    **pVisuals;        /* All of the device's visuals. */
  75.     int        *numOverlayVisuals;    /* Number of OverlayInfo's pointed
  76.                      * to by pOverlayVisuals.  If this
  77.                      * number is zero, the device does
  78.                      * not have overlay planes. */
  79.     OverlayInfo    **pOverlayVisuals;    /* The device's overlay plane visual
  80.                      * information. */
  81.     int        *numImageVisuals;    /* Number of XVisualInfo's pointed
  82.                      * to by pImageVisuals. */
  83.     XVisualInfo    ***pImageVisuals;    /* The device's image visuals. */
  84. {
  85.     XVisualInfo    getVisInfo;        /* Paramters of XGetVisualInfo */
  86.     int        mask;
  87.     XVisualInfo    *pVis, **pIVis;        /* Faster, local copies */
  88.     OverlayInfo    *pOVis;
  89.     OverlayVisualPropertyRec    *pOOldVis;
  90.     int        nVisuals, nOVisuals, nIVisuals;
  91.     Atom    overlayVisualsAtom;    /* Parameters for XGetWindowProperty */
  92.     Atom    actualType;
  93.     unsigned long numLongs, bytesAfter;
  94.     int        actualFormat;
  95.     int        nImageVisualsAlloced;    /* Values to process the XVisualInfo */
  96.     int        imageVisual;        /* array */
  97.  
  98.  
  99.     /* First, get the list of visuals for this screen. */
  100.     getVisInfo.screen = screen;
  101.     mask = VisualScreenMask; 
  102.  
  103.     *pVisuals = XGetVisualInfo(display, mask, &getVisInfo, numVisuals);
  104.     if ((nVisuals = *numVisuals) <= 0)
  105.     {
  106.     /* Return that the information wasn't sucessfully obtained: */
  107.     return(1);
  108.     }
  109.     pVis = *pVisuals;
  110.  
  111.  
  112.     /* Now, get the overlay visual information for this screen.  To obtain
  113.      * this information, get the SERVER_OVERLAY_VISUALS property.
  114.      */
  115.     overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True);
  116.     if (overlayVisualsAtom != None)
  117.     {
  118.     /* Since the Atom exists, we can request the property's contents.  The
  119.      * do-while loop makes sure we get the entire list from the X server.
  120.      */
  121.     bytesAfter = 0;
  122.     numLongs = sizeof(OverlayVisualPropertyRec) / 4;
  123.     do
  124.     {
  125.         numLongs += bytesAfter * 4;
  126.         XGetWindowProperty(display, RootWindow(display, screen),
  127.                    overlayVisualsAtom, 0, numLongs, False,
  128.                    overlayVisualsAtom, &actualType, &actualFormat,
  129.                    &numLongs, &bytesAfter,
  130.                    (unsigned char **) pOverlayVisuals);
  131.     } while (bytesAfter > 0);
  132.  
  133.  
  134.     /* Calculate the number of overlay visuals in the list. */
  135.     *numOverlayVisuals = numLongs / (sizeof(OverlayVisualPropertyRec) / 4);
  136.     }
  137.     else if (
  138.     strcmp(display, "Hewlett-Packard Company") == 0 &&
  139.     XHPGetServerMode(display, screen) == XHPCOMBINED_MODE)
  140.     {
  141.     /* This is an old X server that supports overlay plane windows, but
  142.      * doesn't set the SERVER_OVERLAY_VISUALS propery.  Call a routine
  143.      * to set the property and return an array of OverlayInfo structs.
  144.      * NOTE: This code won't be necessary in the future once all servers
  145.      * that support overlays set this property.
  146.      */
  147.     SetServerOverlayVisualsProperty(display, screen,
  148.                     numOverlayVisuals, pOverlayVisuals);
  149.     }
  150.     else
  151.     {
  152.     /* This screen doesn't have overlay planes. */
  153.     *numOverlayVisuals = 0;
  154.     *pOverlayVisuals = NULL;
  155.     *transparentOverlays = 0;
  156.     }
  157.  
  158.  
  159.     /* Process the pVisuals array. */
  160.     *numImageVisuals = 0;
  161.     nImageVisualsAlloced = 1;
  162.     pIVis = *pImageVisuals = (XVisualInfo **) malloc(4);
  163.     while (--nVisuals >= 0)
  164.     {
  165.     nOVisuals = *numOverlayVisuals;
  166.     pOVis = *pOverlayVisuals;
  167.     imageVisual = True;
  168.     while (--nOVisuals >= 0)
  169.     {
  170.         pOOldVis = (OverlayVisualPropertyRec *) pOVis;
  171.         if (pVis->visualid == pOOldVis->visualID)
  172.         {
  173.         imageVisual = False;
  174.         pOVis->pOverlayVisualInfo = pVis;
  175.         if (pOVis->transparentType == TransparentPixel)
  176.             *transparentOverlays = 1;
  177.         }
  178.         pOVis++;
  179.     }
  180.     if (imageVisual)
  181.     {
  182.         if ((*numImageVisuals += 1) > nImageVisualsAlloced)
  183.         {
  184.         nImageVisualsAlloced++;
  185.         *pImageVisuals = (XVisualInfo **)
  186.             realloc(*pImageVisuals, (nImageVisualsAlloced * 4));
  187.         pIVis = *pImageVisuals + (*numImageVisuals - 1);
  188.         }
  189.         *pIVis++ = pVis;
  190.     }
  191.     pVis++;
  192.     }
  193.  
  194.  
  195.     /* Return that the information was sucessfully obtained: */
  196.     return(0);
  197.  
  198. } /* GetXVisualInfo() */
  199.  
  200.  
  201. /******************************************************************************
  202.  *
  203.  * SetServerOverlayVisualsProperty()
  204.  *
  205.  * This routine sets the property and returns an array of OverlayInfo structs.
  206.  * NOTE: This code won't be necessary in the future once all servers that
  207.  * support overlays set this property.
  208.  *
  209.  ******************************************************************************/
  210.  
  211. static void SetServerOverlayVisualsProperty(display, screen,
  212.                         numOverlayVisuals, pOverlayVisuals)
  213.  
  214.     Display    *display;        /* Which X server (aka "display"). */
  215.     int        screen;            /* Which screen of the "display". */
  216.     int        *numOverlayVisuals;    /* Number of OverlayVisualInfo's
  217.                      * pointed to by pOverlayVisuals.
  218.                      * If this number is zero, the device
  219.                      * does not have overlay planes. */
  220.     OverlayInfo    **pOverlayVisuals;    /* The device's overlay plane visual
  221.                      * information. */
  222. {
  223.     OverlayVisualPropertyRec    *pOVis;
  224.     Atom    overlayVisualsAtom;    /* Parameters for XGetWindowProperty */
  225.  
  226.  
  227.     /* On "old" HP "combined mode" devices, the default visual is the one
  228.      * and only overlay visual.  These devices really support a transparent
  229.      * pixel "value" (which is what the overlay planes are painted with above
  230.      * image planes windows), but they don't yet advertise that pixel value
  231.      * (be careful, with what you look at down there).  The transparent pixel
  232.      * "value" is the same number as the number of colormap entries.  For
  233.      * example, if the device returns a 4-plane overlay visual, the
  234.      * "map_entries" value below is 15 (the colormap has 15 allocatable
  235.      * colors: 0-14), and the transparent pixel value is 15.  If the device
  236.      * returns a 3-plane visual, the "map_entries" value below is 7, and the
  237.      * transparent pixel value is 7.
  238.      */
  239.     pOVis = ((OverlayVisualPropertyRec *)
  240.          malloc(sizeof(OverlayVisualPropertyRec)));
  241.     pOVis->visualID = DefaultVisual(display, screen)->visualid;
  242.     pOVis->transparentType = TransparentPixel;
  243.     pOVis->value = DefaultVisual(display, screen)->map_entries;
  244.     pOVis->layer = 1;
  245.  
  246.     overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", False);
  247.     XChangeProperty(display, RootWindow(display, screen), overlayVisualsAtom,
  248.             overlayVisualsAtom, 32, PropModeReplace,
  249.             (unsigned char *) pOVis, 4);
  250.     XSync(display, False);
  251.  
  252.     weCreateServerOverlayVisualsProperty = True;
  253.  
  254.     *numOverlayVisuals = 1;
  255.     *pOverlayVisuals = (OverlayInfo *) pOVis;
  256.  
  257. } /* SetServerOverlayVisualsProperty() */
  258.  
  259.  
  260. /******************************************************************************
  261.  *
  262.  * FreeXVisualInfo()
  263.  *
  264.  * This routine frees the data that was allocated by GetXVisualInfo().
  265.  *
  266.  ******************************************************************************/
  267.  
  268. void FreeXVisualInfo(pVisuals, pOverlayVisuals, pImageVisuals)
  269.  
  270.     XVisualInfo    *pVisuals;
  271.     OverlayInfo    *pOverlayVisuals;
  272.     XVisualInfo    **pImageVisuals;
  273. {
  274.     XFree(pVisuals);
  275.     if (weCreateServerOverlayVisualsProperty)
  276.     free(pOverlayVisuals);
  277.     else
  278.     XFree(pOverlayVisuals);
  279.     free(pImageVisuals);
  280.  
  281. } /* FreeXVisualInfo() */
  282.  
  283.  
  284. /******************************************************************************
  285.  *
  286.  * FindImagePlanesVisual()
  287.  *
  288.  * This routine attempts to find a visual to use to create an image planes
  289.  * window based upon the information passed in.
  290.  *
  291.  * The "Hint" values give guides to the routine as to what the program wants.
  292.  * The "depthFlexibility" value tells the routine how much the program wants
  293.  * the actual "depthHint" specified.  If the program can't live with the
  294.  * screen's image planes visuals, the routine returns non-zero, and the
  295.  * "depthObtained" and "pImageVisualToUse" return parameters are NOT valid.
  296.  * Otherwise, the "depthObtained" and "pImageVisualToUse" return parameters
  297.  * are valid and the routine returns zero.
  298.  *
  299.  * NOTE: This is just an example of what can be done.  It may or may not be
  300.  * useful for any specific application.
  301.  *
  302.  ******************************************************************************/
  303.  
  304. int FindImagePlanesVisual(display, screen, numImageVisuals, pImageVisuals,
  305.               sbCmapHint, depthHint, depthFlexibility,
  306.               pImageVisualToUse, depthObtained)
  307.  
  308.     Display    *display;        /* Which X server (aka "display"). */
  309.     int        screen;            /* Which screen of the "display". */
  310.     int        numImageVisuals;    /* Number of XVisualInfo's pointed
  311.                      * to by pImageVisuals. */
  312.     XVisualInfo    **pImageVisuals;    /* The device's image visuals. */
  313.     int        sbCmapHint;        /* What Starbase cmap modes will be
  314.                      * used with the visual.  NOTE: This
  315.                      * is a mask of the possible values. */
  316.     int        depthHint;        /* Desired depth. */
  317.     int        depthFlexibility;    /* How much the actual value in
  318.                      * "depthHint" is desired. */
  319.     Visual    **pImageVisualToUse;    /* The screen's image visual to use. */
  320.     int        *depthObtained;        /* Actual depth of the visual. */
  321. {
  322.     XVisualInfo    *pVisualInfoToUse;    /* The current best visual to use. */
  323.     int        i;
  324.     int        visMask;
  325.     int        curDelta, newDelta;
  326.  
  327.  
  328.  
  329.     switch (sbCmapHint)
  330.     {
  331.     case SB_CMAP_TYPE_NORMAL:
  332.     case SB_CMAP_TYPE_NORMAL | SB_CMAP_TYPE_MONOTONIC:
  333.     case SB_CMAP_TYPE_NORMAL | SB_CMAP_TYPE_MONOTONIC | SB_CMAP_TYPE_FULL:
  334.     case SB_CMAP_TYPE_NORMAL | SB_CMAP_TYPE_FULL:
  335.         visMask = GRAY_SCALE | PSEUDO_COLOR;
  336.         break;
  337.     case SB_CMAP_TYPE_MONOTONIC:
  338.         visMask = STATIC_GRAY | GRAY_SCALE | PSEUDO_COLOR;
  339.         break;
  340.     case SB_CMAP_TYPE_MONOTONIC | SB_CMAP_TYPE_FULL:
  341.         visMask = GRAY_SCALE | PSEUDO_COLOR;
  342.         break;
  343.     case SB_CMAP_TYPE_FULL:
  344.         visMask = GRAY_SCALE | PSEUDO_COLOR | TRUE_COLOR | DIRECT_COLOR;
  345.         break;
  346.     default:
  347.         /* The caller didn't specify a valid combination of CMAP_ type: */
  348.         return(1);
  349.     } /* switch (sbCmapHint) */
  350.  
  351.  
  352.     pVisualInfoToUse = NULL;
  353.  
  354.     for (i = 0 ; i < numImageVisuals ; i++)
  355.     {
  356.     switch (pImageVisuals[i]->class)
  357.     {
  358.         case StaticGray:
  359.         if (visMask & STATIC_GRAY)
  360.         {
  361.             if (pVisualInfoToUse == NULL)
  362.             {
  363.             if ((pImageVisuals[i]->depth == depthHint) ||
  364.                 depthFlexibility)
  365.             {
  366.                 pVisualInfoToUse = pImageVisuals[i];
  367.             }
  368.             }
  369.             else
  370.             {
  371.             if (pImageVisuals[i]->depth == depthHint)
  372.                 pVisualInfoToUse = pImageVisuals[i];
  373.             else if (depthFlexibility)
  374.             {
  375.                 /* The basic hueristic used is to find the closest
  376.                  * depth to "depthHint" that's also greater than
  377.                  * "depthHint", or just the closest depth:
  378.                  */
  379.                 if ((curDelta = pVisualInfoToUse->depth -
  380.                  depthHint) > 0)
  381.                 {
  382.                 /* Only choose this new visual if it's also
  383.                  * deeper than "depthHint" and closer to
  384.                  * "depthHint" than the currently chosen visual:
  385.                  */
  386.                 if (((newDelta = pImageVisuals[i]->depth -
  387.                       depthHint) > 0) && (newDelta < curDelta))
  388.                 {
  389.                     pVisualInfoToUse = pImageVisuals[i];
  390.                 }
  391.                 }
  392.                 else
  393.                 {
  394.                 /* Choose this new visual if it's deeper than
  395.                  * "depthHint" or closer to "depthHint" than
  396.                  * the currently chosen visual:
  397.                  */
  398.                 if (((newDelta = pImageVisuals[i]->depth -
  399.                       depthHint) > 0) ||
  400.                     (-newDelta < -curDelta))
  401.                 {
  402.                     pVisualInfoToUse = pImageVisuals[i];
  403.                 }
  404.                 }
  405.             }
  406.             }
  407.         }
  408.         break;
  409.         case GrayScale:
  410.         if (visMask & GRAY_SCALE)
  411.         {
  412.             if (pVisualInfoToUse == NULL)
  413.             {
  414.             if ((pImageVisuals[i]->depth == depthHint) ||
  415.                 depthFlexibility)
  416.             {
  417.                 pVisualInfoToUse = pImageVisuals[i];
  418.             }
  419.             }
  420.             else if (!((sbCmapHint & SB_CMAP_TYPE_FULL) &&
  421.                    (pVisualInfoToUse->class == DirectColor)))
  422.             {
  423.             if (pImageVisuals[i]->depth == depthHint)
  424.                 pVisualInfoToUse = pImageVisuals[i];
  425.             else if (depthFlexibility)
  426.             {
  427.                 /* The basic hueristic used is to find the closest
  428.                  * depth to "depthHint" that's also greater than
  429.                  * "depthHint", or just the closest depth:
  430.                  */
  431.                 if ((curDelta = pVisualInfoToUse->depth -
  432.                  depthHint) > 0)
  433.                 {
  434.                 /* Only choose this new visual if it's also
  435.                  * deeper than "depthHint" and closer to
  436.                  * "depthHint" than the currently chosen visual:
  437.                  */
  438.                 if (((newDelta = pImageVisuals[i]->depth -
  439.                       depthHint) > 0) && (newDelta < curDelta))
  440.                 {
  441.                     pVisualInfoToUse = pImageVisuals[i];
  442.                 }
  443.                 }
  444.                 else
  445.                 {
  446.                 /* Choose this new visual if it's deeper than
  447.                  * "depthHint" or closer to "depthHint" than
  448.                  * the currently chosen visual:
  449.                  */
  450.                 if (((newDelta = pImageVisuals[i]->depth -
  451.                       depthHint) > 0) ||
  452.                     (-newDelta < -curDelta))
  453.                 {
  454.                     pVisualInfoToUse = pImageVisuals[i];
  455.                 }
  456.                 }
  457.             }
  458.             }
  459.         }
  460.         break;
  461.         case PseudoColor:
  462.         if (visMask & PSEUDO_COLOR)
  463.         {
  464.             if (pVisualInfoToUse == NULL)
  465.             {
  466.             if ((pImageVisuals[i]->depth == depthHint) ||
  467.                 depthFlexibility)
  468.             {
  469.                 pVisualInfoToUse = pImageVisuals[i];
  470.             }
  471.             }
  472.             else if (!((sbCmapHint & SB_CMAP_TYPE_FULL) &&
  473.                    (pVisualInfoToUse->class == DirectColor)))
  474.             {
  475.             if (pImageVisuals[i]->depth == depthHint)
  476.                 pVisualInfoToUse = pImageVisuals[i];
  477.             else if (depthFlexibility)
  478.             {
  479.                 /* The basic hueristic used is to find the closest
  480.                  * depth to "depthHint" that's also greater than
  481.                  * "depthHint", or just the closest depth:
  482.                  */
  483.                 if ((curDelta = pVisualInfoToUse->depth -
  484.                  depthHint) > 0)
  485.                 {
  486.                 /* Only choose this new visual if it's also
  487.                  * deeper than "depthHint" and closer to
  488.                  * "depthHint" than the currently chosen visual:
  489.                  */
  490.                 if (((newDelta = pImageVisuals[i]->depth -
  491.                       depthHint) > 0) && (newDelta < curDelta))
  492.                 {
  493.                     pVisualInfoToUse = pImageVisuals[i];
  494.                 }
  495.                 }
  496.                 else
  497.                 {
  498.                 /* Choose this new visual if it's deeper than
  499.                  * "depthHint" or closer to "depthHint" than
  500.                  * the currently chosen visual:
  501.                  */
  502.                 if (((newDelta = pImageVisuals[i]->depth -
  503.                       depthHint) > 0) ||
  504.                     (-newDelta < -curDelta))
  505.                 {
  506.                     pVisualInfoToUse = pImageVisuals[i];
  507.                 }
  508.                 }
  509.             }
  510.             }
  511.         }
  512.         break;
  513.         case StaticColor:
  514.         /* Starbase doesn't work well with StaticColor visuals: */
  515.         break;
  516.         case TrueColor:
  517.         if (visMask & TRUE_COLOR)
  518.         {
  519.             /* The only Starbase cmap type that TrueColor works with
  520.              * is SB_CMAP_TYPE_FULL, so we know that SB_CMAP_TYPE_FULL
  521.              * is what the program wants:
  522.              */
  523.             if (pVisualInfoToUse == NULL)
  524.             {
  525.             if ((pImageVisuals[i]->depth == depthHint) ||
  526.                 depthFlexibility)
  527.             {
  528.                 pVisualInfoToUse = pImageVisuals[i];
  529.             }
  530.             }
  531.             /* This example code prefers DirectColor to TrueColor: */
  532.             else if (pVisualInfoToUse->class != DirectColor)
  533.             {
  534.             if (pImageVisuals[i]->depth == depthHint)
  535.                 pVisualInfoToUse = pImageVisuals[i];
  536.             else if (depthFlexibility)
  537.             {
  538.                 /* The basic hueristic used is to find the closest
  539.                  * depth to "depthHint" that's also greater than
  540.                  * "depthHint", or just the closest depth:
  541.                  */
  542.                 if ((curDelta = pVisualInfoToUse->depth -
  543.                  depthHint) > 0)
  544.                 {
  545.                 /* Only choose this new visual if it's also
  546.                  * deeper than "depthHint" and closer to
  547.                  * "depthHint" than the currently chosen visual:
  548.                  */
  549.                 if (((newDelta = pImageVisuals[i]->depth -
  550.                       depthHint) > 0) && (newDelta < curDelta))
  551.                 {
  552.                     pVisualInfoToUse = pImageVisuals[i];
  553.                 }
  554.                 }
  555.                 else
  556.                 {
  557.                 /* Choose this new visual if it's deeper than
  558.                  * "depthHint" or closer to "depthHint" than
  559.                  * the currently chosen visual:
  560.                  */
  561.                 if (((newDelta = pImageVisuals[i]->depth -
  562.                       depthHint) > 0) ||
  563.                     (-newDelta < -curDelta))
  564.                 {
  565.                     pVisualInfoToUse = pImageVisuals[i];
  566.                 }
  567.                 }
  568.             }
  569.             }
  570.         }
  571.         break;
  572.         case DirectColor:
  573.         if (visMask & DIRECT_COLOR)
  574.         {
  575.             if (pVisualInfoToUse == NULL)
  576.             {
  577.             if ((pImageVisuals[i]->depth == depthHint) ||
  578.                 depthFlexibility)
  579.             {
  580.                 pVisualInfoToUse = pImageVisuals[i];
  581.             }
  582.             }
  583.             else
  584.             {
  585.             if (pImageVisuals[i]->depth == depthHint)
  586.                 pVisualInfoToUse = pImageVisuals[i];
  587.             else if (depthFlexibility)
  588.             {
  589.                 /* The basic hueristic used is to find the closest
  590.                  * depth to "depthHint" that's also greater than
  591.                  * "depthHint", or just the closest depth:
  592.                  */
  593.                 if ((curDelta = pVisualInfoToUse->depth -
  594.                  depthHint) > 0)
  595.                 {
  596.                 /* Only choose this new visual if it's also
  597.                  * deeper than "depthHint" and closer to
  598.                  * "depthHint" than the currently chosen visual:
  599.                  */
  600.                 if (((newDelta = pImageVisuals[i]->depth -
  601.                       depthHint) > 0) && (newDelta < curDelta))
  602.                 {
  603.                     pVisualInfoToUse = pImageVisuals[i];
  604.                 }
  605.                 }
  606.                 else
  607.                 {
  608.                 /* Choose this new visual if it's deeper than
  609.                  * "depthHint" or closer to "depthHint" than
  610.                  * the currently chosen visual:
  611.                  */
  612.                 if (((newDelta = pImageVisuals[i]->depth -
  613.                       depthHint) > 0) ||
  614.                     (-newDelta < -curDelta))
  615.                 {
  616.                     pVisualInfoToUse = pImageVisuals[i];
  617.                 }
  618.                 }
  619.             }
  620.             }
  621.         }
  622.         break;
  623.     } /* switch (pImageVisuals[i]->class) */
  624.     } /* for (i = 0 ; i < numImageVisuals ; i++) */
  625.  
  626.  
  627.     if (pVisualInfoToUse != NULL)
  628.     {
  629.     *pImageVisualToUse = pVisualInfoToUse->visual;
  630.     *depthObtained = pVisualInfoToUse->depth;
  631.     return(0);
  632.     }
  633.     else
  634.     {
  635.     /* Couldn't find an appropriate visual class: */
  636.     return(1);
  637.     }
  638.  
  639. } /* FindImagePlanesVisual() */
  640.  
  641.  
  642. /******************************************************************************
  643.  *
  644.  * FindOverlayPlanesVisual()
  645.  *
  646.  * This routine attempts to find a visual to use to create an overlay planes
  647.  * window based upon the information passed in.
  648.  *
  649.  * While the CreateImagePlanesWindow() routine took a sbCmapHint, this
  650.  * routine doesn't.  Starbase's CMAP_FULL shouldn't be used in overlay planes
  651.  * windows.  This is partially because this functionality is better suited in
  652.  * the image planes where there are generally more planes, and partially
  653.  * because the overlay planes generally have PseudoColor visuals with one
  654.  * color being transparent (the transparent normally being the "white" color
  655.  * for CMAP_FULL).
  656.  *
  657.  * The "depthHint" values give guides to the routine as to what depth the
  658.  * program wants the window to be.  The "depthFlexibility" value tells the
  659.  * routine how much the program wants the actual "depthHint" specified.  If
  660.  * the program can't live with the screen's overlay planes visuals, the
  661.  * routine returns non-zero, and the "depthObtained" and "pOverlayVisualToUse"
  662.  * return parameters are NOT valid.  Otherwise, the "depthObtained" and
  663.  * "pOverlayVisualToUse" return parameters are valid and the routine returns
  664.  * zero.
  665.  *
  666.  * NOTE: This is just an example of what can be done.  It may or may not be
  667.  * useful for any specific application.
  668.  *
  669.  ******************************************************************************/
  670.  
  671. int FindOverlayPlanesVisual(display, screen, numOverlayVisuals, pOverlayVisuals,
  672.                 depthHint, depthFlexibility, transparentBackground,
  673.                 pOverlayVisualToUse, depthObtained,
  674.                 transparentColor)
  675.  
  676.     Display    *display;        /* Which X server (aka "display"). */
  677.     int        screen;            /* Which screen of the "display". */
  678.     int        numOverlayVisuals;    /* Number of OverlayInfo's pointed
  679.                      * to by pOverlayVisuals. */
  680.     OverlayInfo    *pOverlayVisuals;    /* The device's overlay plane visual
  681.                      * information. */
  682.     int        depthHint;        /* Desired depth. */
  683.     int        depthFlexibility;    /* How much the actual value in
  684.                      * "depthHint" is desired. */
  685.     int        transparentBackground;    /* Non-zero if the visual must have
  686.                      * a transparent color. */
  687.     Visual    **pOverlayVisualToUse;    /* The screen's overlay visual to
  688.                      * use. */
  689.     int        *depthObtained;        /* Actual depth of the visual. */
  690.     int        *transparentColor;    /* The transparent color the program
  691.                      * can use with the visual. */
  692. {
  693.     XVisualInfo    *pCandidateVisual;    /* Fast/local pointer. */
  694.     XVisualInfo    *pVisualInfoToUse;    /* The current best visual to use. */
  695.     int        i;
  696.     int        visMask;
  697.     int        curDelta, newDelta;
  698.  
  699.  
  700.  
  701.     pVisualInfoToUse = NULL;
  702.  
  703.     for (i = 0 ; i < numOverlayVisuals ; i++)
  704.     {
  705.     pCandidateVisual = pOverlayVisuals[i].pOverlayVisualInfo;
  706.     if (pVisualInfoToUse == NULL)
  707.     {
  708.         if (((pCandidateVisual->depth == depthHint) || depthFlexibility) &&
  709.         !transparentBackground ||
  710.         (pOverlayVisuals[i].transparentType == TransparentPixel))
  711.         {
  712.         pVisualInfoToUse = pCandidateVisual;
  713.         *transparentColor = pOverlayVisuals[i].value;
  714.         }
  715.     }
  716.     else if (!transparentBackground ||
  717.          (pOverlayVisuals[i].transparentType == TransparentPixel))
  718.     {
  719.         if (pCandidateVisual->depth == depthHint)
  720.         {
  721.         pVisualInfoToUse = pCandidateVisual;
  722.         *transparentColor = pOverlayVisuals[i].value;
  723.         }
  724.         else if (depthFlexibility)
  725.         {
  726.         /* The basic hueristic used is to find the closest depth to
  727.          * "depthHint" that's also greater than "depthHint", or just
  728.          * the closest depth:
  729.          */
  730.         if ((curDelta = pVisualInfoToUse->depth - depthHint) > 0)
  731.         {
  732.             /* Only choose this new visual if it's also deeper than
  733.              * "depthHint" and closer to "depthHint" than the currently
  734.              * chosen visual:
  735.              */
  736.             if (((newDelta = pCandidateVisual->depth - depthHint) > 0)
  737.             && (newDelta < curDelta))
  738.             {
  739.             pVisualInfoToUse = pCandidateVisual;
  740.             *transparentColor = pOverlayVisuals[i].value;
  741.             }
  742.         }
  743.         else
  744.         {
  745.             /* Choose this new visual if it's deeper than "depthHint"
  746.              * or closer to "depthHint" than the currently chosen
  747.              * visual:
  748.              */
  749.             if (((newDelta = pCandidateVisual->depth - depthHint) > 0)
  750.             || (-newDelta < -curDelta))
  751.             {
  752.             pVisualInfoToUse = pCandidateVisual;
  753.             *transparentColor = pOverlayVisuals[i].value;
  754.             }
  755.         }
  756.         }
  757.     }
  758.     } /* for (i = 0 ; i < numOverlayVisuals ; i++) */
  759.  
  760.  
  761.     if (pVisualInfoToUse != NULL)
  762.     {
  763.     *pOverlayVisualToUse = pVisualInfoToUse->visual;
  764.     *depthObtained = pVisualInfoToUse->depth;
  765.     return(0);
  766.     }
  767.     else
  768.     {
  769.     /* Couldn't find an appropriate visual class: */
  770.     return(1);
  771.     }
  772.  
  773. } /* FindOverlayPlanesVisual() */
  774.  
  775.  
  776. /******************************************************************************
  777.  *
  778.  * CreateImagePlanesWindow()
  779.  *
  780.  * This routine creates an image planes window, potentially creates a colormap
  781.  * for the window to use, and sets the window's standard properties, based
  782.  * upon the information passed in to the routine.  While "created," the window
  783.  * has not been mapped.
  784.  *
  785.  * If the routine suceeds, it returns zero and the return parameters
  786.  * "imageWindow", "imageColormap" and "mustFreeImageColormap" are valid.
  787.  * Otherwise, the routine returns non-zero and the return parameters are
  788.  * NOT valid.
  789.  *
  790.  * NOTE: This is just an example of what can be done.  It may or may not be
  791.  * useful for any specific application.
  792.  *
  793.  ******************************************************************************/
  794.  
  795. int CreateImagePlanesWindow(display, screen, parentWindow,
  796.                 windowX, windowY, windowWidth, windowHeight,
  797.                 windowDepth, pImageVisualToUse,
  798.                 argc, argv, windowName, iconName,
  799.                 imageWindow, imageColormap, mustFreeImageColormap)
  800.  
  801.     Display    *display;        /* Which X server (aka "display"). */
  802.     int        screen;            /* Which screen of the "display". */
  803.     Window    parentWindow;        /* Window ID of the parent window for
  804.                      * the created window. */
  805.     int        windowX;        /* Desired X coord. of the window. */
  806.     int        windowY;        /* Desired Y coord of the window. */
  807.     int        windowWidth;        /* Desired width of the window. */
  808.     int        windowHeight;        /* Desired height of the window. */
  809.     int        windowDepth;        /* Desired depth of the window. */
  810.     Visual    *pImageVisualToUse;    /* The window's image planes visual. */
  811.     int        argc;            /* Program's argc parameter. */
  812.     char    *argv[];        /* Program's argv parameter. */
  813.     char    *windowName;        /* Name to put on window's border. */
  814.     char    *iconName;        /* Name to put on window's icon. */
  815.     Window    *imageWindow;        /* Window ID of the created window. */
  816.     Colormap    *imageColormap;        /* The window's colormap. */
  817.     int        *mustFreeImageColormap;    /* Non-zero if the program must call
  818.                      * XFreeColormap() for imageColormap. */
  819. {
  820.     XSetWindowAttributes winAttributes;    /* Attributes for window creation */
  821.     XSizeHints    hints;
  822.  
  823.  
  824.  
  825.     if (pImageVisualToUse == DefaultVisual(display, screen))
  826.     {
  827.     *mustFreeImageColormap = False;
  828.     *imageColormap = winAttributes.colormap = DefaultColormap(display,
  829.                                   screen);
  830.     winAttributes.background_pixel = BlackPixel(display, screen);
  831.     winAttributes.border_pixel = WhitePixel(display, screen);
  832.     }
  833.     else
  834.     {
  835.     XColor        actualColor, databaseColor;
  836.  
  837.     *mustFreeImageColormap = True;
  838.     *imageColormap = winAttributes.colormap =
  839.         XCreateColormap(display, RootWindow(display, screen),
  840.                 pImageVisualToUse, AllocNone);
  841.     XAllocNamedColor(display, winAttributes.colormap, "Black",
  842.              &actualColor, &databaseColor);
  843.     winAttributes.background_pixel = actualColor.pixel;
  844.     XAllocNamedColor(display, winAttributes.colormap, "White",
  845.              &actualColor, &databaseColor);
  846.     winAttributes.border_pixel = actualColor.pixel;
  847.     }
  848.     winAttributes.event_mask = ExposureMask;
  849.  
  850.  
  851.     *imageWindow = XCreateWindow(display, parentWindow,
  852.                  0, 0, windowWidth, windowHeight, 2,
  853.                  windowDepth, InputOutput, pImageVisualToUse,
  854.                  (CWBackPixel | CWColormap |
  855.                   CWBorderPixel | CWEventMask),
  856.                  &winAttributes);
  857.  
  858.  
  859.     hints.flags = (USSize | USPosition);
  860.     hints.x = windowX;
  861.     hints.y = windowY;
  862.     hints.width  = windowWidth;
  863.     hints.height = windowHeight;
  864.     XSetStandardProperties(display, *imageWindow, windowName, iconName,
  865.                None, argv, argc, &hints);
  866.  
  867.  
  868.     return(0);
  869.  
  870. } /* CreateImagePlanesWindow() */
  871.  
  872.  
  873. /******************************************************************************
  874.  *
  875.  * CreateOverlayPlanesWindow()
  876.  *
  877.  * This routine creates an overlay planes window, potentially creates a colormap
  878.  * for the window to use, and sets the window's standard properties, based
  879.  * upon the information passed in to the routine.  While "created," the window
  880.  * has not been mapped.
  881.  *
  882.  * If the routine suceeds, it returns zero and the return parameters
  883.  * "overlayWindow", "overlayColormap" and "mustFreeOverlayColormap" are valid.
  884.  * Otherwise, the routine returns non-zero and the return parameters are
  885.  * NOT valid.
  886.  *
  887.  * NOTE: This is just an example of what can be done.  It may or may not be
  888.  * useful for any specific application.
  889.  *
  890.  ******************************************************************************/
  891.  
  892. int CreateOverlayPlanesWindow(display, screen, parentWindow,
  893.                   windowX, windowY, windowWidth, windowHeight,
  894.                   windowDepth, pOverlayVisualToUse,
  895.                   argc, argv, windowName, iconName,
  896.                   transparentBackground, transparentColor,
  897.                   overlayWindow, overlayColormap,
  898.                   mustFreeOverlayColormap)
  899.  
  900.     Display    *display;        /* Which X server (aka "display"). */
  901.     int        screen;            /* Which screen of the "display". */
  902.     Window    parentWindow;        /* Window ID of the parent window for
  903.                      * the created window. */
  904.     int        windowX;        /* Desired X coord. of the window. */
  905.     int        windowY;        /* Desired Y coord of the window. */
  906.     int        windowWidth;        /* Desired width of the window. */
  907.     int        windowHeight;        /* Desired height of the window. */
  908.     int        windowDepth;        /* Desired depth of the window. */
  909.     Visual    *pOverlayVisualToUse;    /* The window's overlay planes visual.*/
  910.     int        argc;            /* Program's argc parameter. */
  911.     char    *argv[];        /* Program's argv parameter. */
  912.     char    *windowName;        /* Name to put on window's border. */
  913.     char    *iconName;        /* Name to put on window's icon. */
  914.     int        transparentBackground;    /* Non-zero if the window's background
  915.                      * should be a transparent color. */
  916.     int        *transparentColor;    /* The transparent color to use as the
  917.                      * window's background. */
  918.     Window    *overlayWindow;        /* Window ID of the created window. */
  919.     Colormap    *overlayColormap;    /* The window's colormap. */
  920.     int        *mustFreeOverlayColormap;/* Non-zero if the program must call
  921.                       * XFreeColormap() for
  922.                       * overlayColormap. */
  923. {
  924.     XSetWindowAttributes winAttributes;    /* Attributes for window creation */
  925.     XSizeHints    hints;
  926.     int        borderWidth;
  927.  
  928.  
  929.  
  930.     if (pOverlayVisualToUse == DefaultVisual(display, screen))
  931.     {
  932.     *mustFreeOverlayColormap = False;
  933.     *overlayColormap = winAttributes.colormap = DefaultColormap(display,
  934.                                     screen);
  935.     if (transparentBackground)
  936.         winAttributes.background_pixel = *transparentColor;
  937.     else
  938.         winAttributes.background_pixel = BlackPixel(display, screen);
  939.     winAttributes.border_pixel = WhitePixel(display, screen);
  940.     }
  941.     else
  942.     {
  943.     XColor        actualColor, databaseColor;
  944.  
  945.     *mustFreeOverlayColormap = True;
  946.     *overlayColormap = winAttributes.colormap =
  947.         XCreateColormap(display, RootWindow(display, screen),
  948.                 pOverlayVisualToUse, AllocNone);
  949.     if (transparentBackground)
  950.         winAttributes.background_pixel = *transparentColor;
  951.     else
  952.     {
  953.         XAllocNamedColor(display, winAttributes.colormap, "Black",
  954.                  &actualColor, &databaseColor);
  955.         winAttributes.background_pixel = actualColor.pixel;
  956.     }
  957.     XAllocNamedColor(display, winAttributes.colormap, "White",
  958.              &actualColor, &databaseColor);
  959.     winAttributes.border_pixel = actualColor.pixel;
  960.     }
  961.     winAttributes.event_mask = ExposureMask;
  962.  
  963.  
  964.     if (transparentBackground && (parentWindow == RootWindow(display, screen)))
  965.     borderWidth = 2;
  966.     else
  967.     borderWidth = 0;
  968.  
  969.  
  970.     *overlayWindow = XCreateWindow(display, parentWindow,
  971.                    0, 0, windowWidth, windowHeight,
  972.                    borderWidth, windowDepth, InputOutput,
  973.                    pOverlayVisualToUse,
  974.                    (CWBackPixel | CWColormap |
  975.                     CWBorderPixel | CWEventMask),
  976.                    &winAttributes);
  977.  
  978.  
  979.     hints.flags = (USSize | PPosition);
  980.     hints.x = windowX;
  981.     hints.y = windowY;
  982.     hints.width  = windowWidth;
  983.     hints.height = windowHeight;
  984.     XSetStandardProperties(display, *overlayWindow, windowName, iconName,
  985.                None, argv, argc, &hints);
  986.  
  987.  
  988.     return(0);
  989.  
  990. } /* CreateOverlayPlanesWindow() */
  991.